001    /* $RCSfile: DESede2KeySpec.java,v $
002     * $Revision: 1.10 $
003     * $Date: 2002/11/23 11:09:57 $
004     * $Author: uwe_guenther $
005     * $State: Exp $
006     *
007     * Created on August 11, 2001 11:18 AM
008     *
009     * Copyright (C) 2001 Uwe Guenther <uwe@cscc.de>
010     *
011     * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
012     * ServiceProvider is a library, written in JavaTM, that should be 
013     * used in HBCI banking applications (clients and may be servers),
014     * to do cryptographic operations.
015     *
016     * The jhbci library is free software; you can redistribute it and/or
017     * modify it under the terms of the GNU Lesser General Public
018     * License as published by the Free Software Foundation; either
019     * version 2.1 of the License, or (at your option) any later version.
020     *
021     * The jhbci library is distributed in the hope that it will be useful,
022     * but WITHOUT ANY WARRANTY; without even the implied warranty of
023     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
024     * Lesser General Public License for more details.
025     *
026     * You should have received a copy of the GNU Lesser General Public
027     * License along with this library; if not, write to the Free Software
028     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
029     *
030     */
031    
032    package de.cscc.crypto.provider.spec;
033    
034    import java.security.InvalidKeyException;
035    
036    /** 
037     * 2 Key Triple DES secret key specification (112 bit or 128 bit with parity)
038     * class.
039     *
040     * <p>This class is immutable.
041     *
042     * @author  <a href=mailto:uwe@cscc.de>Uwe Günther</a>
043     * @version $Revision: 1.10 $
044     */
045    public class DESede2KeySpec implements DESKeySpec, Cloneable {
046    
047        /** Key length in bytes. */        
048        private static final int DES_EDE_2KEY_LEN = 16;
049    
050        /** Internal data representation of key1. */    
051        private DES1KeySpec key1;
052        
053        /** Internal data representation of key2. */        
054        private DES1KeySpec key2;
055        
056        /**
057         * Creates a new DESede2KeySpec from a 16 bytes long byte array.
058         * We use the first 16 bytes in key as the key material for the DES key.
059         *
060         * The first (leftmost) DES key (key[0] to key[7]) is key1 and
061         * the second (rightmost) DES key (key[8] to key[15]) is key2.
062         *
063         * @param key the buffer with the two DES keys.
064         * @throws InvalidKeyException if the given key material is shorter
065         *                              than 16 bytes or the key is weak or semi weak.
066         */
067        public DESede2KeySpec(byte[] key) throws InvalidKeyException {
068            this(key, 0);
069        }
070        
071        /** 
072         * Creates a new DESede2KeySpec from a 16 bytes long byte array .
073         *
074         * @param key the buffer with the DES keys.
075         * @param offset the offset in key, where the key starts.
076         * @throws InvalidKeyException if the given key material is shorter
077         *                              than 16 bytes or the key is weak or semi weak.
078         */
079        public DESede2KeySpec(byte[] key, int offset) throws InvalidKeyException {   
080            this.key1 = new DES1KeySpec(key, offset+0);
081            this.key2 = new DES1KeySpec(key, offset+8);
082        }
083    
084        /**
085         * Creates a new DESede2KeySpec from an existing one.
086         *
087         * @param key DesKeySpec object with a key.
088         */
089        public DESede2KeySpec(DESede2KeySpec key) {
090            this.key1 = new DES1KeySpec(key.key1);
091            this.key2 = new DES1KeySpec(key.key2);
092        } 
093    
094        
095        /**
096         * Creates and returns a deep copy of this object.
097         *
098         * @return a clone of this instance.
099         * @see java.lang.Cloneable
100         * @exception CloneNotSupportedException if the object's class does not
101         *             support the <code>Cloneable</code> interface. Subclasses
102         *             that override the <code>clone</code> method can also
103         *             throw this exception to indicate that an instance cannot
104         *             be cloned.
105         */        
106        public Object clone() throws CloneNotSupportedException {
107            DESede2KeySpec result = (DESede2KeySpec) super.clone();
108            result.key1 = (DES1KeySpec) this.key1.clone();
109            result.key2 = (DES1KeySpec) this.key2.clone();
110            return result;
111        }
112        
113        
114        /**
115         * Indicates whether some other object is "equal to" this one.
116         *
117         * @param   obj   the reference object with which to compare.
118         * @return  <code>true</code> if this object is the same as the obj
119         *         argument; <code>false</code> otherwise.
120         * @see     #hashCode()
121         * @see     java.util.Hashtable
122         */        
123        public boolean equals(Object obj) {
124             //Only for performance.
125            if (this == obj) {
126                return true;
127            } 
128            
129            //If obj == null then instanceof returns false, see JLS 15.20.2
130            if (!(obj instanceof DESede2KeySpec)) {
131                return false;
132            }
133            
134            DESede2KeySpec other = (DESede2KeySpec)obj;
135            return this.key1.equals(other.key1) &&
136                   this.key2.equals(other.key2)  ;
137        }
138        
139        /**
140         * Returns a hash code value for the object. 
141         *
142         * @return  a hash code value for this object.
143         * @see     #equals(java.lang.Object)
144         * @see     java.util.Hashtable
145         */    
146        public int hashCode() {
147            int result = 17;
148            result = 37*result + this.key1.hashCode();
149            result = 37*result + this.key2.hashCode();
150            return result;
151        }    
152    
153        
154        /**
155         * Returns a string representation of the object. 
156         *
157         * @return  a string representation of the object.
158         */     
159        public String toString() { 
160            return "key1: [" + this.key1 + "] " +
161                   "key2: [" + this.key2 + "]";
162        }
163    
164        
165        /** 
166         * Get the DES Key as byte[16].
167         *
168         * @return the DES Key as byte[16]. 
169         */    
170        public byte[] getKey() {
171            byte[] returnValue = new byte[16];
172            System.arraycopy(this.key1.getKey(), 0, returnValue, 0, 8);
173            System.arraycopy(this.key2.getKey(), 0, returnValue, 8, 8);
174            return returnValue;
175        }
176        
177    }